package home.game.client.controllers;

import home.game.client.display.MainFrame;
import home.game.client.display.models.PlayerType;
import home.game.client.display.models.Tile;
import home.game.client.utils.ImageLoader;
import home.game.entity.User;

import java.awt.image.BufferedImage;
import java.util.Observable;
import java.util.Random;

/**
 */
public class BoardController implements Controller {
    private static final BufferedImage PLAYER_ICON = ImageLoader.loadImage("client/src/main/resources/x.png");
    private static final BufferedImage AI_ICON = ImageLoader.loadImage("client/src/main/resources/o.png");
    private int moves;

    private PlayerType controllable;
    private Tile[] board;
    private User user;
    PlayerType winner;

    public BoardController(User user) {
        this.user = user;
    }

    public void initController(Controllable... board) {
        controllable = PlayerType.Player;
        this.board = (Tile[]) board;
        moves = 0;
    }

    @Override
    public void update(Observable o, Object arg) {
        switch (controllable) {
            case Player: {
                controllable = PlayerType.AI;
            }
            break;
            case AI: {
                controllable = PlayerType.Player;
            }
            break;
        }
        if (moves < 8) {
            if (controllable == PlayerType.AI) {
                Random random = new Random();
                while (true) {
                    int i = random.nextInt(9);
                    if (board[i].getTileObject() == null) {
                        board[i].setTileObject(AI_ICON);
                        board[i].setOwner(PlayerType.AI);
                        break;
                    }
                }
            }
            moves++;


            if ((winner = isGameOver()) != null && controllable != PlayerType.GameOver) {
                controllable = PlayerType.GameOver;
                if (winner == PlayerType.Player) {
                    user.setScore(user.getScore() + (9 - moves));
                    Application.getInstance().getUserManager().updateUserScore(user);
                    MainFrame.getInstance().showEndGame(winner);
                }


            }
        } else {
            controllable = PlayerType.GameOver;
            Application.getInstance().getUserManager().updateUserScore(user);
            MainFrame.getInstance().showEndGame(controllable);

        }
        ((Tile) o).getPanel().repaint();

    }


    public PlayerType getInControl() {
        return controllable;
    }

    public BufferedImage getInControlIcon() {
        switch (controllable) {
            case Player:
                return PLAYER_ICON;
            case AI:
                return AI_ICON;
        }
        return null;
    }

    private PlayerType isGameOver() {
        for (int i = 0; i < 3; i++) {
            if (checkEquals(board[i * 3].getOwner(), board[i * 3 + 1].getOwner()) &&
                    checkEquals(board[i * 3].getOwner(), board[i * 3 + 2].getOwner())
                    ) {
                return board[i].getOwner();
            } else if (checkEquals(board[i].getOwner(), board[i + 3].getOwner()) &&
                    checkEquals(board[i].getOwner(), board[i + 6].getOwner())) {
                return board[i].getOwner();
            } else if (checkEquals(board[0].getOwner(), board[4].getOwner()) && checkEquals(board[0].getOwner(), board[8].getOwner())) {
                return board[0].getOwner();
            } else if (checkEquals(board[2].getOwner(), board[4].getOwner()) && checkEquals(board[0].getOwner(), board[6].getOwner())) {
                return board[2].getOwner();
            }
        }
        return null;
    }

    private boolean checkEquals(PlayerType type1, PlayerType type2) {
        return type1 != null & type2 != null && type1 == type2;
    }
}
